﻿using System;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Web;
using TidyBlog.Entity;
using TidyBlog.Util;
using TidyBlog.Data;
using TidyBlog.DAL;

namespace TidyBlog.BLL
{
    /// <summary>
    /// 用户业务逻辑层
    /// </summary>
    public class UserBLL
    {
        /// <summary>
        /// 验证用户属性
        /// </summary>
        /// <param name="user"></param>
        public static void Validate(User user)
        {
            if (String.IsNullOrEmpty(user.Password) || user.Password.Length < 6)
            {
                throw new ArgumentException("密码长度不能小于6位");
            }
            else if (user.Password.Length != 40)
            {
                user.Password = Encrypt.ToSHA1(user.Password);
            }

            if (!String.IsNullOrEmpty(user.Email) && !Validator.IsEmail(user.Email))
            {
                throw new ArgumentException("Email格式错误");
            }
            if (!String.IsNullOrEmpty(user.HomePage))
            {
                user.HomePage = Validator.fixUrl(user.HomePage);
            }
            if (!String.IsNullOrEmpty(user.QQ) && !Validator.IsQQ(user.QQ))
            {
                throw new ArgumentException("QQ号码格式错误");
            }
            if (String.IsNullOrEmpty(user.Nickname))
            {
                user.Nickname = user.UserName;
            }
        }

        /// <summary>
        /// 读取用户
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <returns>用户</returns>
        public static User Read(int userId)
        {
            try
            {
                return UserDAL.Read(userId);
            }
            catch
            {
#if DEBUG
                throw;
#else
                throw new Exception("读取用户记录出错");
#endif
            }
        }

        /// <summary>
        /// 根据用户名和密码读取用户
        /// </summary>
        /// <param name="userName">用户名</param>
        /// <param name="password">密码，如果密码为null，则只通过用户名读取</param>
        /// <returns>用户</returns>
        public static User Read(string userName, string password)
        {
            if (String.IsNullOrEmpty(userName))
            {
                throw new Exception("用户名不能为空");
            }
            if (String.IsNullOrEmpty(password))
            {
                throw new Exception("密码不能为空");
            }

            try
            {
                return UserDAL.Read(userName, password);
            }
            catch
            {
#if DEBUG
                throw;
#else
                throw new Exception("读取用户记录出错");
#endif
            }
        }

        /// <summary>
        /// 创建用户
        /// </summary>
        /// <param name="user">用户</param>
        public static void Create(User user)
        {
            if (!Regex.IsMatch(user.UserName, @"^\w{2,20}$"))
            {
                throw new ArgumentException("用户名必须由2-20位字母、数字或下划线组成");
            }

            Validate(user);
            if (UserDAL.IsNameExist(user.UserName))
            {
                throw new ArgumentException("用户名已被注册");
            }
            if (UserDAL.IsNameExist(user.Nickname))
            {
                throw new ArgumentException("昵称已被注册");
            }

            user.RegTime = DateTime.UtcNow;
            user.LastActivity = user.RegTime;

            try
            {
                UserDAL.Create(user);
            }
            catch
            {
#if DEBUG
                throw;
#else
                throw new Exception("创建用户记录出错");
#endif
            }
        }

        /// <summary>
        /// 更新用户
        ///</summary>
        ///<param name="user">用户</param>
        public static void Update(User user)
        {
            Validate(user);

            // 是否有相同昵称的用户是否存在
            User refUser = UserDAL.Read(user.Nickname);
            // 用户Id与当前用户Id不同时，说明有其他用户使用了此昵称
            if (refUser != null && refUser.UserId != user.UserId)
            {
                throw new ArgumentException("昵称已被使用");
            }

            // 为每一个用户保留与用户名相同的昵称，因此昵称不能与现有用户名重复
            refUser = UserDAL.Read(user.Nickname, null);
            if (refUser != null && refUser.UserId != user.UserId)
            {
                throw new ArgumentException("昵称已被使用");
            }

            try
            {
                UserDAL.Update(user);
            }
            catch
            {
#if DEBUG
                throw;
#else
                throw new Exception("更新用户记录出错");
#endif
            }
        }

        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="userId">用户编号</param>
        public static void Delete(int userId)
        {
            try
            {
                UserDAL.Delete(userId);
            }
            catch
            {
#if DEBUG
                throw;
#else
                throw new Exception("删除用户记录出错");
#endif
            }
        }

        /// <summary>
        /// 搜索用户
        /// </summary>
        /// <param name="conditions">搜索条件</param>
        /// <param name="pageSize">每页显示记录数</param>
        /// <param name="currentPage">当前页</param>
        /// <returns>搜索结果</returns>
        public static DataPaging<User> List(Dictionary<string, string> queryParams, ushort pageSize, int currentPage)
        {
            try
            {
                return UserDAL.List(queryParams, pageSize, currentPage);
            }
            catch
            {
#if DEBUG
                throw;
#else
                throw new Exception("搜索用户出错");
#endif
            }
        }

        /// <summary>
        /// 更新用户状态
        /// </summary>
        /// <param name="userId">用户编号</param>
        /// <param name="lastIP">最后活动IP</param>
        public static void UpdateState(int userId, string lastIP)
        {
            try
            {
                UserDAL.UpdateState(userId, DateTime.UtcNow, lastIP);
            }
            catch
            {
#if DEBUG
                throw;
#else
                throw new Exception("更新用户状态出错");
#endif
            }
        }
    }
}
